<?php
/***********************************************************************
 * @package    IvanEngine
 * @subpackage Core
 * @author     Ivan <ivanzx@msn.com>
 * @created    2010-05-12
 ***********************************************************************/
if(defined("IVANENGINE_CORE_IO_FILESTREAM"))
	die("Redefinition macro in :".__FILE__."(".__LINE__.")");
define("IVANENGINE_CORE_IO_FILESTREAM", true);

require_once (dirname(__FILE__).'/../Common.php');
require_once (dirname(__FILE__).'/DataStream.php');

class CFileSteam extends CDataStream
{
    protected $m_hFile;
    protected $m_fileName;

    public function __construct($filename, $mode='r+b')
    {
        parent::__construct();
        $this->Open($filename, $mode);
    }
	
    public function __destruct()
    {
    	parent::__destruct();
    }
    
    public function Open($filename, $mode='r+b')
    {
        // $php_errormsg is a variable containing the text 
        // of the last error message generated by PHP.
        global $php_errormsg;
        
        if (strpos($mode, 'w') === false  &&  !is_readable($filename)) {
            // opening for reading non-readable file
            throw new CException('File \'' . $filename . '\' is not readable.');
        }

        $trackErrors = ini_get('track_errors');
        ini_set('track_errors', '1');

        $this->m_hFile = @fopen($filename, $mode);

        if ($this->m_hFile === false) {
            ini_set('track_errors', $trackErrors);
            throw new CException($php_errormsg);
        }

        ini_set('track_errors', $trackErrors);
        $this->SetName($filename);
    }
    
    public function Seek($offset, $whence=SEEK_SET)
    {
        return fseek($this->m_hFile, $offset, $whence);
    }


    public function Tell()
    {
        return ftell($this->m_hFile);
    }

    public function Flush()
    {
        return fflush($this->m_hFile);
    }

    public function Close()
    {
        if ($this->m_hFile !== null ) {
            @fclose($this->m_hFile);
            $this->m_hFile = null;
        }
    }

    public function Size()
    {
        $position = ftell($this->m_hFile);
        fseek($this->m_hFile, 0, SEEK_END);
        $size = ftell($this->m_hFile);
        fseek($this->m_hFile,$position);

        return $size;
    }

    public function Read($length = 1)
    {
        if ($length == 0) {
            return '';
        }

        if ($length < 1024) {
            return fread($this->m_hFile, $length);
        }

        $data = '';
        while ( $length > 0 && ($nextBlock = fread($this->m_hFile, $length)) != false ) {
            $data .= $nextBlock;
            $length -= strlen($nextBlock);
        }
        return $data;
    }

    public function Write($data, $length=null)
    {
        if ($length === null ) {
            fwrite($this->m_hFile, $data);
        } else {
            fwrite($this->m_hFile, $data, $length);
        }
    }

    public function Lock($lockType, $nonBlockingLock = false)
    {
        if ($nonBlockingLock) {
            return flock($this->m_hFile, $lockType | LOCK_NB);
        } else {
            return flock($this->m_hFile, $lockType);
        }
    }

    public function Unlock()
    {
        if ($this->m_hFile !== null ) {
            return flock($this->m_hFile, LOCK_UN);
        } else {
            return true;
        }
    }
}

?>